// 问题描述：设置最大并发量max，放入 n 个任务来异步执行，一个任务执行完再加入另一个任务，直到 n 个任务都执行完，再执行某个任务 ( m < n )
const max = 5       // 最大并发量为 5
var arr = []
const n = 50

// 设置任务时间
function getRandomTimeOut(){
    return Math.random()*5000       // 取0-5000间的随机整数
}

// 并发执行
function test(n, max, callback) {
    let todoArr = [],  // 存储并发量为max的promise数组
        i = 0;

    function todo() {
        if (i === n) {   
            // 所有的都处理完了，返回一个resolve
            return Promise.resolve();
        }else{
            let one = new Promise((resolve)=>{      // 设置一个任务
                setTimeout(() => {
                    resolve()
                }, getRandomTimeOut()); 
            }); 
            // console.log(one)
            i ++
            todoArr.push(one);  // 将当前的promise存入并发数组中
            console.log(`第${i}个任务入队`)
            one.then( () => {
                todoArr.splice(todoArr.indexOf(one), 1)     // 当一个promise执行完毕后，从数组删除
                console.log(`第${i}个任务执行完成，出队`)
            });
            
            let p = Promise.resolve();
            if (todoArr.length >= max) {     // 当并行数量达到最大后，用race比较 第一个完成的，然后再调用一下函数自身。
                p = Promise.race(todoArr);
            }
            return p.then(() => todo());
        }
    }
    
    // arr循环完后， 现在todoArr里面剩下最后max个promise对象，使用all等待所有的都完成之后执行callback
    todo().then(() => Promise.all(todoArr)).then(() => {
        callback();
    })
}


test(n,max,function callback(){
    console.log(`${n}个任务执行完毕`)
})